﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace CartoGraphic.Model2
{
    public abstract class BaseDrawingObj : IComparable
    {
        private bool selected;
        private Color bordercolor;
        private Color fillColor;
        private bool filled;
        private string type;

        private int penWidth;
        //private Pen drawpen;
        //private Brush drawBrush;
        private DrawingPens.PenType _penType;
        private FillBrushes.BrushType _brushType;
        private string tipText;

        private static Color lastUsedColor = Color.Black;
        private static int lastUsedPenWidth = 1;

        private const string entryColor = "Color";
        private const string entryPenWidth = "PenWidth";
        private const string entryPen = "DrawPen";
        private const string entryBrush = "DrawBrush";
        private const string entryFillColor = "FillColor";
        private const string entryFilled = "Filled";
        private const string entryZOrder = "ZOrder";
        private const string entryTipText = "TipText";

        private bool dirty;
        private int _id;
        private int _zOrder;
        private int _rotation = 0;
        private Point _center;
        private string code="Unknown";
        private string info="Unknown";
        private string dimension = "Unknown";


        #region Properties

        public string Dimension
        {
            get { return dimension; }
            set { dimension = value; }
        }

        public string Code
        {
            get { return code; }
            set { code = value; }
        }

        public string Info
        {
            get { return info; }
            set { info = value; }
        }
		public Point Center
		{
			get { return _center; }
			set { _center = value; }
		}

        public string Type
        {
           get { return type; }
			set { type = value; }
        }

		public int Rotation
		{
			get { return _rotation; }
			set
			{
				if (value > 360)
					_rotation = value - 360;
				else if (value < -360)
					_rotation = value + 360;
				else
					_rotation = value;
			}
		}

		public int ZOrder
		{
			get { return _zOrder; }
			set { _zOrder = value; }
		}

		public int ID
		{
			get { return _id; }
			set { _id = value; }
		}

		public bool Dirty
		{
			get { return dirty; }
			set { dirty = value; }
		}

		public bool Filled
		{
			get { return filled; }
			set { filled = value; }
		}

		public bool Selected
		{
			get { return selected; }
			set { selected = value; }
		}

		public Color FillColor
		{
			get { return fillColor; }
			set { fillColor = value; }
		}

		public Color Color
		{
			get { return bordercolor; }
            set { bordercolor = value; }
		}

        public int PenWidth
        {
            get { return penWidth; }
            set { penWidth = value; }
        }

		public FillBrushes.BrushType BrushType
		{
			get { return _brushType; }
			set { _brushType = value; }
		}

        //public Brush DrawBrush
        //{
        //    get { return drawBrush; }
        //    set { drawBrush = value; }
        //}

		public DrawingPens.PenType PenType
		{
			get { return _penType; }
			set { _penType = value; }
		}

        //public Pen DrawPen
        //{
        //    get { return drawpen; }
        //    set { drawpen = value; }
        //}

		public virtual int HandleCount
		{
			get { return 0; }
		}

		public virtual int ConnectionCount
		{
			get { return 0; }
		}

		public static Color LastUsedColor
		{
			get { return lastUsedColor; }
			set { lastUsedColor = value; }
		}

		public static int LastUsedPenWidth
		{
			get { return lastUsedPenWidth; }
			set { lastUsedPenWidth = value; }
		}

		public string TipText
		{
			get { return tipText; }
			set { tipText = value; }
		}

		#endregion Properties
		#region Constructor

		protected BaseDrawingObj()
		{
			ID = GetHashCode();
		}
		#endregion

		#region Virtual Functions

		public abstract BaseDrawingObj Clone();

        public virtual void Draw(Graphics g, GraphicsProperties gps)
		{
		}

        protected void FillDrawObjectFields(BaseDrawingObj drawObject)
        {
            drawObject.selected = selected;
            drawObject.bordercolor = bordercolor;
            drawObject.penWidth = penWidth;
            drawObject.ID = ID;
            drawObject._brushType = _brushType;
            drawObject._penType = _penType;
            //drawObject.drawBrush = drawBrush;
            //drawObject.drawpen = drawpen;
            drawObject.fillColor = fillColor;
            drawObject._rotation = _rotation;
            drawObject._center = _center;
        }

		#region Selection handle methods

		public virtual Point GetHandle(int handleNumber)
		{
			return new Point(0, 0);
		}

		public virtual Rectangle GetHandleRectangle(int handleNumber)
		{
			Point point = GetHandle(handleNumber);
			return new Rectangle(point.X - (penWidth + 3), point.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
		}

		public virtual void DrawTracker(Graphics g)
		{
			if (!Selected)
				return;
			SolidBrush brush = new SolidBrush(Color.Black);

			for (int i = 1; i <= HandleCount; i++)
			{
				g.FillRectangle(brush, GetHandleRectangle(i));
			}
			brush.Dispose();
		}
		#endregion Selection handle methods
		#region Connection Point methods

		public virtual Point GetConnection(int connectionNumber)
		{
			return new Point(0, 0);
		}

		public virtual Rectangle GetConnectionEllipse(int connectionNumber)
		{
			Point p = GetConnection(connectionNumber);
			// Take into account width of pen
			return new Rectangle(p.X - (penWidth + 3), p.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
		}
		public virtual void DrawConnection(Graphics g, int connectionNumber)
		{
			SolidBrush b = new SolidBrush(System.Drawing.Color.Red);
			Pen p = new Pen(System.Drawing.Color.Red, -1.0f);
			g.DrawEllipse(p, GetConnectionEllipse(connectionNumber));
			g.FillEllipse(b, GetConnectionEllipse(connectionNumber));
			p.Dispose();
			b.Dispose();
		}

		public virtual void DrawConnections(Graphics g)
		{
			if (!Selected)
				return;
			SolidBrush b = new SolidBrush(System.Drawing.Color.White);
			Pen p = new Pen(System.Drawing.Color.Black, -1.0f);
			for (int i = 0; i < ConnectionCount; i++)
			{
				g.DrawEllipse(p, GetConnectionEllipse(i));
				g.FillEllipse(b, GetConnectionEllipse(i));
			}
			p.Dispose();
			b.Dispose();
		}
		#endregion Connection Point methods

		public virtual int HitTest(Point point)
		{
			return -1;
		}

		protected virtual bool PointInObject(Point point)
		{
			return false;
		}

		public virtual Cursor GetHandleCursor(int handleNumber)
		{
			return Cursors.Default;
		}


		public virtual bool IntersectsWith(Rectangle rectangle)
		{
			return false;
		}

		public virtual void Move(int deltaX, int deltaY)
		{
		}

		public virtual void MoveHandleTo(Point point, int handleNumber)
		{
		}

		public virtual void Dump()
		{
			Trace.WriteLine("");
			Trace.WriteLine(GetType().Name);
			Trace.WriteLine("Selected = " + selected.ToString(CultureInfo.InvariantCulture));
		}

		public virtual void Normalize()
		{
		}

		#region Save / Load methods

		public virtual void SaveToStream(SerializationInfo info, int orderNumber, int objectIndex)
		{
			
		}

		public virtual void LoadFromStream(SerializationInfo info, int orderNumber, int objectData)
		{
			
		}
		#endregion Save/Load methods
		#endregion Virtual Functions

		#region Other functions

		protected void Initialize()
		{
		}

		protected void FillBaseDrawingObjFields(BaseDrawingObj BaseDrawingObj)
		{
			BaseDrawingObj.selected = selected;
            BaseDrawingObj.bordercolor = bordercolor;
			BaseDrawingObj.penWidth = penWidth;
			BaseDrawingObj.ID = ID;
			BaseDrawingObj._brushType = _brushType;
			BaseDrawingObj._penType = _penType;
            //BaseDrawingObj.drawBrush = drawBrush;
            //BaseDrawingObj.drawpen = drawpen;
			BaseDrawingObj.fillColor = fillColor;
			BaseDrawingObj._rotation = _rotation;
			BaseDrawingObj._center = _center;
		}
		#endregion Other functions

		#region IComparable Members
		public int CompareTo(object obj)
		{
			BaseDrawingObj d = obj as BaseDrawingObj;
			int x = 0;
			if (d != null)
				if (d.ZOrder == ZOrder)
					x = 0;
				else if (d.ZOrder > ZOrder)
					x = -1;
				else
					x = 1;

			return x;
		}
		#endregion IComparable Members
    }
}
